using System;
using System.Linq;
using System.Security.Principal;

namespace YawetagLib.Security
{
    [Serializable]
    public sealed class UserContext : MarshalByRefObject, IPrincipal, IUser
    {
        [NonSerialized] private readonly IUser _user;

        public UserContext(IIdentity identity, int userID, string identifier, Guid sessionID, string[] roles, IUserLocator userLocator = null)
        {
            Identity = identity;

            UserID = userID;
            Identifier = identifier;
            SessionID = sessionID;
            Roles = roles;

            UserLocator = userLocator;
        }

        public UserContext(IIdentity identity, IUser user, Guid sessionID, string[] roles)
            : this(identity, user.UserID, user.Identifier, sessionID, roles, null)
        {
            _user = user;
        }

        public bool IsInRole(string role)
        {
            return Roles.Contains(role);
        }

        public IIdentity Identity { get; private set; }

        public bool IsAuthenticated
        {
            get { return Identity.IsAuthenticated; }
        }

        public int UserID { get; private set; }
        public string Identifier { get; private set; }
        public Guid SessionID { get; private set; }
        public string[] Roles { get; private set; }

        public IUser User
        {
            get { return _user ?? (UserLocator != null ? UserLocator.Get(UserID) : null); }
        }

        public string FullName
        {
            get { return User != null ? User.FullName : string.Empty; }
        }

        private IUserLocator UserLocator { get; set; }
    }
}
